from application import *
from views import *
from agents import *
from gamestate import GameState
import os


class AbstractCommandM(AbstractModel):
    def __init__(self,game):
        AbstractModel.__init__(self)
        self.game=game           
        
class AbstractPrototypeCommandM(AbstractCommandM):
    def __init__(self, prototype,game):
        AbstractCommandM.__init__(self,game)
        self.prototype=prototype        
    def _GetViewClass(self,contextId):      
        return ModelPrototypeV
        
class ObjectTemplateCmdM(AbstractPrototypeCommandM):
    def Activate(self):
        return PaintTemplateObjectA(self.prototype)

class EraserCmdM(AbstractPrototypeCommandM):  
    def Activate(self): return EraserA()
    
class PlayPauseCmdV(ModelPrototypeV):
    def GetFrame(self):
        return GetApplication().game.state==1
    
class PlayPauseCmdM(AbstractPrototypeCommandM):   
    def Activate(self):
        if self.game.state==GameState.playing:
            self.game.controler.SetGameState(GameState.paused)
        elif self.game.state==GameState.paused or self.game.state==GameState.stoped:
            self.game.controler.SetGameState(GameState.playing)   
        return 0
    def _GetViewClass(self,contextId):
        return PlayPauseCmdV
                 
class StopCmdM(AbstractPrototypeCommandM):   
    def Activate(self): 
        if self.game.state==GameState.paused or self.game.state==GameState.playing:
            self.game.controler.SetGameState(GameState.stoped) 
        return 0

class NewCmdM(AbstractPrototypeCommandM):   
    def Activate(self): 
        self.game.controler.NewMap()
        return 0


class LoadCmdM(AbstractPrototypeCommandM):   
    def Activate(self):
        dir=os.getcwd()
        defaultdir=os.path.join(dir,"maps")
        default=os.path.join(defaultdir,"map01.map")
    
        try:
            import win32gui, win32con, pywintypes
            try:
                fname, customfilter, flags = win32gui.GetOpenFileNameW(
                                               InitialDir=defaultdir , 
                                               Flags=win32con.OFN_EXPLORER,
                                               File="map01",DefExt="map", 
                                               Title="Open borgwar map", 
                                               Filter='Borgwar map (*.map)\0*.map\0' , 
                                               CustomFilter='Other file types (*.*)\0*.*\0',                                           
                                               FilterIndex=1)                                               
            
                self.game.controler.LoadMap(fname)
            except pywintypes.error:
                #Operation canceled
                pass
            os.chdir(dir)
            return 0
        except ImportError:
            default=os.path.join("maps","map01.map")
            if os.path.isfile(default):
                self.game.controler.LoadMap(default)
            
            

class SaveCmdM(AbstractPrototypeCommandM):   
    def Activate(self): 
        dir=os.getcwd()
        defaultdir=os.path.join(dir,"maps")
        default=os.path.join(defaultdir,"map01.map")   
        try:
            import win32gui, win32con, pywintypes
            try:
                fname, customfilter, flags = win32gui.GetSaveFileNameW(
                                               InitialDir=defaultdir , 
                                               Flags=win32con.OFN_EXPLORER,
                                               File="map01",DefExt="map", 
                                               Title="Save borgwar map", 
                                               Filter='Borgwar map (*.map)\0*.map\0' , 
                                               CustomFilter='Other file types (*.*)\0*.*\0',                                           
                                               FilterIndex=1)
                                               
            
                self.game.controler.SaveMap(fname)
            except pywintypes.error:
                #Operation canceled
                pass
            os.chdir(dir)
            return 0
        except ImportError:            
            self.game.controler.SaveMap(default)
        
class CellTemplateCmdM(AbstractPrototypeCommandM):
    def Activate(self): return PaintTemplateCellA(self.prototype)    
    
class ToolPaletteV(AbstractView):
    def __init__(self, model,contextId):
        AbstractView.__init__(self, model,contextId)        
        self.y_offset=0
        self.y_offset_max=0
    def Build(self):
        AbstractView.Build(self)
        self.childs=[t.BuildView(self.contextId) for t in self.model.tools]        
        self.area=pygame.Rect(self.model.area)
        self.pick=pygame.Rect(self.model.area)
        self.pick.topleft=(0,0)        
        self.ComputePosition()
    def ComputePosition(self):
        #now place the tools in the palette
        current_y=0
        current_x=0        
        step=max([max(c.pick.width,c.pick.height) for c in self.childs])
        self.childs.sort(key=lambda a:a.model.prototype.sortkey)
        for c in self.childs:
            if current_x+step>self.area.width:  #cariage return !
                current_x=0
                current_y+=step
            c.pos=(current_x+step*.5  , self.y_offset+current_y+step*.5)
            current_x+=step
            c.Build()
        self.y_offset_max=current_y
    """def Draw(self, surface):
        if self.area:  surface=surface.subsurface(self.area)
        surface.fill((0,0,0))
        for c in self.childs:
            c.Draw(surface) """

class ScrollPaletteV(ToolPaletteV):
    def  __init__(self, model,contextId):
        ToolPaletteV.__init__(self, model,contextId)
        self.y_offset_target=0
    def ProcessModelNotif(self, notif):                 
        if isinstance(notif,UpdateNotif):            
            if self.y_offset==self.y_offset_target:
                return
            elif abs(self.y_offset_target-self.y_offset)<5:
                self.y_offset=self.y_offset_target
                self.ComputePosition()
            else:
                self.y_offset=(self.y_offset_target+self.y_offset)/2.
                self.ComputePosition()
                
    def ScrollModel(self,p):
        #print "===========",p
        self.y_offset_target-=p*64
        self.y_offset_target=max(self.y_offset_target,-self.y_offset_max)
        self.y_offset_target=min(self.y_offset_target,0)

            
    
        
    
class ToolPaletteM(AbstractModel):
    def __init__(self,prototype,game,controler=0):
        AbstractModel.__init__(self,controler)  
        self.prototype=prototype   
        self.tools=[] #tools available from the tool palette
        self.area=pygame.Rect(*prototype.rectangle)
        toolsmodelclass=prototype.toolsmodelclass        
        for protoId, proto in game.prototypes.items():           
            #it there a tool for this type ?
            if proto.type in toolsmodelclass:
                self.tools.append(toolsmodelclass[proto.type](proto,game))                
    def _GetViewClass(self,contextId):
        return ToolPaletteV  
class UpdateNotif:
    pass
class ScrollPaletteC(AbstractDynamicControler):
    def Update(self):
        self.model.NotifyViews(UpdateNotif())
class ScrollPaletteM(ToolPaletteM): 
    def _GetViewClass(self,contextId):
        return ScrollPaletteV  
    def __init__(self,prototype,game):
        ToolPaletteM.__init__(self,prototype,game,ScrollPaletteC(self))
   
            
          
        
       